import { IRegularPolygon, ICustomPloygon, IShape, Point, DrawMode } from './../model';
import { BoundingBox } from './../base';
import { PointUtil } from './../utils';

export class RegularPolygon extends BoundingBox {

    type: DrawMode;
    x: number;
    y: number;
    count: number;
    border: number;
    rotate = 0;

    constructor(options: IRegularPolygon) {
        super();
        this.type = options.type;
        this.count = options.count;
        this.x = options.x;
        this.y = options.y;
        this.border = options.border;
        this.rotate = options.rotate || 0;
    }

    update() {

    }

    render(ctx: CanvasRenderingContext2D) {
        const singleAngle = Math.PI * 2 / this.count;
        const length = this.border / 2 / Math.sin(singleAngle / 2);
        ctx.save();
        ctx.translate(this.x, this.y);
        ctx.rotate(this.rotate);
        ctx.beginPath();
        const fillPath = new Path2D();
        fillPath.moveTo(length, 0);
        for (let i = 0; i <= this.count; i++) {
            const currentAngle = i * singleAngle;
            const xPosition = Math.cos(currentAngle) * length;
            const yPosition = Math.sin(currentAngle) * length;
            fillPath.lineTo(xPosition, yPosition);
        }
        ctx.closePath();
        this.type === 'stroke' ? ctx.stroke(fillPath) : ctx.fill(fillPath);
        ctx.restore();
    }
}

export class UnRegularPolygon extends BoundingBox implements IShape {

    points: Point[];
    type: DrawMode;

    constructor(customPloygon: ICustomPloygon) {
        super();
        this.type = customPloygon.type;
        this.points = customPloygon.points;
        this.controlRect = this.getControlRect();
        this.getShapeCenterPoint();
    }

    render(ctx: CanvasRenderingContext2D) {
        ctx.strokeStyle = '#ea0000';
        if (!this.points.length) {
            return;
        }
        ctx.save();
        this.handleAction(ctx);
        ctx.beginPath();
        const fillPath = new Path2D();
        const { x: x0, y: y0 } = this.points[0];
        fillPath.moveTo(x0, y0);
        this.points.forEach(({ x, y }) => {
            fillPath.lineTo(x, y);
        });
        fillPath.lineTo(x0, y0);
        ctx.closePath();
        this.type === 'stroke' ? ctx.stroke(fillPath) : ctx.fill(fillPath);
        ctx.restore();
    }

    checkClick(ctx: CanvasRenderingContext2D, point: Point): boolean {
        const checkResult = this.getPointIsInsideArea(point);
        if (checkResult) {
            this.drawBorder(ctx);
            this.drawControls(ctx);
        }
        return checkResult;
    }


    getControlRect() {
        return PointUtil.getControlRect(this.points);
    }

    getPointIsInsideArea(point: Point): boolean {
        point = this.transferOriginPoint(point);
        return PointUtil.getPointIsInsideArea(point, this.points);
    }
}



